package OOJ;

import java.io.*;

/**
 * Hulpklasse voor gebruik van standaardin- en uitvoer
 * @author Arend Rensink
 * @version 1.0
 */
public class Console {
    /** teken voor een fout in de invoer */
    static public final char FOUT = '\u0004';

    static private BufferedReader in =
	new BufferedReader(new InputStreamReader(System.in));
    static private PrintStream out = System.out;

    private Console() {}

    /**
     * Schrijft een test op standaarduitvoer.
     * @param tekst de te schrijven tekst
     */
    static public void print(String tekst) {
	out.print(tekst);
    }

    /**
     * Schrijft een test op standaarduitvoer, afgesloten met een regelovergang.
     * @param tekst de te schrijven tekst
     */
    static public void println(String tekst) {
	out.println(tekst);
    }

    /**
     * Leest een regel tekst van standaardinvoer.
     * Bij wijze van vraag wordt eerst een tekst weergegeven.
     * @param tekst vraagtekst
     * @return ingelezen tekst; is nooit null
     */
    static public String readString(String tekst) {
	print(tekst);
	String antw = null;
	try {
	    antw = in.readLine();
	} catch (IOException e) {
	}

	if (antw == null)
	    return ""+FOUT;
	else 
	    return antw;
    }

    /**
     * Leest een geheel getal van standaardinvoer.
     * Bij wijze van vraag wordt eerst een tekst weergegeven.
     * Bij ongeldige invoer (geen geheel getal) volgt een foutboodschap,
     * en wordt de vraag herhaald tot een geldige antwoord is gegeven.
     * @param tekst vraagtekst
     * @return ingevoerd getal
     */
    static public int readInt(String tekst) {
	return readInt(tekst, "Voer een geheel getal in");
    }

    /**
     * Leest een geheel getal van standaardinvoer.
     * Bij wijze van vraag wordt eerst een tekst weergegeven.
     * Bij ongeldige invoer (geen geheel getal) volgt een foutboodschap,
     * en wordt de vraag herhaald tot een geldige antwoord is gegeven.
     * @param tekst vraagtekst
     * @param foutboodschap tekst die gegeven wordt bij foutieve invoer
     * @return ingevoerd getal
     */
    static public int readInt(String tekst, String foutboodschap) {
	do {
	    String antw = readString(tekst);
	    try {
		return Integer.parseInt(antw);
	    }
	    catch (NumberFormatException e) {
		println(foutboodschap);
	    }
	}
        while (true);
    }

    /**
     * Leest een gebroken getal van standaardinvoer.
     * Bij wijze van vraag wordt eerst een tekst weergegeven.
     * Bij ongeldige invoer (geen gebroken getal) volgt een foutboodschap,
     * en wordt de vraag herhaald tot een geldige antwoord is gegeven.
     * @param tekst vraagtekst
     * @return ingevoerd getal
     */
    static public double readDouble(String tekst) {
	return readDouble(tekst, "Voer een gebroken getal in");
    }

    /**
     * Leest een gebroken getal van standaardinvoer.
     * Bij wijze van vraag wordt eerst een tekst weergegeven.
     * Bij ongeldige invoer (geen gebroken getal) volgt een foutboodschap,
     * en wordt de vraag herhaald tot een geldige antwoord is gegeven.
     * @param tekst vraagtekst
     * @param foutboodschap tekst die gegeven wordt bij foutieve invoer
     * @return ingevoerd getal
     */
    static public double readDouble(String tekst, String foutboodschap) {
	do {
	    String antw = readString(tekst);
	    try {
		return Double.parseDouble(antw);
	    } catch (NumberFormatException e) {
		println(foutboodschap);
	    }
	}
        while (true);
    }

    /**
     * Leest een enkel teken van standaardinvoer.
     * Bij wijze van vraag wordt eerst een tekst weergegeven.
     * Bij ongeldige invoer (0 tekens of meer dan 1) volgt een foutboodschap,
     * en wordt de vraag herhaald tot een geldige antwoord is gegeven.
     * @param tekst vraagtekst
     * @return ingevoerd teken; 
     * FOUT als bij het lezen een fout opgetreden is (bijv. einde file)
     */
    static public char readChar(String tekst) {
	return readChar(tekst, "Voer precies 1 teken in");
    }

    /**
     * Leest een enkel teken van standaardinvoer.
     * Bij wijze van vraag wordt eerst een tekst weergegeven.
     * Bij ongeldige invoer (0 tekens of meer dan 1) volgt een foutboodschap,
     * en wordt de vraag herhaald tot een geldige antwoord is gegeven.
     * @param tekst vraagtekst
     * @param foutboodschap tekst die gegeven wordt bij foutieve invoer
     * @return ingevoerd teken; 
     * FOUT als bij het lezen een fout opgetreden is (bijv. einde file)
     */
    static public char readChar(String tekst, String foutboodschap) {
	String antw;
	do {
	    antw = readString(tekst);
	    if (antw.length() != 1)
		println(foutboodschap);
	} while (antw.length() != 1);
	return antw.charAt(0);
    }

    /**
     * Leest een waarheidswaarde van standaardinvoer.
     * Bij wijze van vraag wordt eerst een tekst weergegeven.
     * Bij ongeldige invoer (geen ja of nee) volgt een foutboodschap,
     * en wordt de vraag herhaald tot een geldige antwoord is gegeven.
     * @param tekst vraagtekst
     * @param ja het antwoord dat "true" oplevert
     * @param nee het antwoord dat "false" oplevert
     * @return ingevoerde waarheidswaarde
     */
    static public boolean readBoolean(String tekst, String ja, String nee) {
	return readBoolean(tekst, ja, nee, "Voer "+ja+" of "+nee+" in");
    }

    /**
     * Leest een waarheidswaarde van standaardinvoer.
     * Bij wijze van vraag wordt eerst een tekst weergegeven.
     * Bij ongeldige invoer (geen ja of nee) volgt een foutboodschap,
     * en wordt de vraag herhaald tot een geldige antwoord is gegeven.
     * @param tekst vraagtekst
     * @param ja het antwoord dat "true" oplevert
     * @param nee het antwoord dat "false" oplevert
     * @param foutboodschap tekst die gegeven wordt bij foutieve invoer
     * @return ingevoerde waarheidswaarde
     */
    static public boolean readBoolean(String tekst, String ja, String nee, 
				      String foutboodschap) {
	do {
	    String antw = readString(tekst);
	    if (antw.equals(ja)) return true;
	    else if (antw.equals(nee)) return false;
	} while (true);
    }
}
